#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stropts.h>

int mousefd = -1;

void sig_fun() {
    int data = 0;
    int n = read(mousefd, &data, sizeof(data));
    if (n < 0) {
        printf("read mouse error\n");
    }
    else {
        printf("%d\n", data);
    }
}

/**
 * System V异步IO示例
 * 由于鼠标不是STREAMS设备, 无法演示
 * 异步IO读取鼠标数据: 鼠标驱动产生鼠标数据时, 发送SIPOLL信号给进程, 通知读取数据
 * 配置异步IO步骤:
 * 1. 调用signal/sigaction为SIGPOLL建立信号处理程序
 * 2. 调用ioctl 设置第二个参数I_SETSIG,第三个参用于读写数据数
 */
int main () {
    int ret;
    int mousepos;

    mousefd = open("/dev/input/mouse0", O_RDONLY);
    if (mousefd < 0) {
        perror("open mouse error");
        exit(0);
    }


    struct sigaction sa;
    struct sigaction od_sa;

    sa.sa_handler = sig_fun;
    sigemptyset(&sa.sa_mask);
    sigaddset(&sa.sa_mask, SIGPOLL); 
    sa.sa_flags = 0;

    sigaction(SIGPOLL, &sa, &od_sa);

    ret = ioctl(mousefd, I_SETSIG, S_INPUT);
    if (ret < 0) {
        perror("ioctl");
        exit(1);
    }

    while (1) {
        usleep(50);
    }

    sigaction(SIGIO, &od_sa, NULL); // 恢复signal mask

    close(mousefd); // 不可达
    return 0;
}
